/*************************************************************************
 *                                                                       *
 * This file is part of the FreeMAPs distribution.  For full copyright   *
 * information, see COPYRIGHT and COPYING.LESSER.                        *
 *                                                                       *
 * Author:           sqbang                                              *
 * Email:            sqbang@ustc.edu                                     *
 * Date:             2012.09.06                                          *
 *                                                                       *
 *************************************************************************/

//declaration header
#include "COMMON/equa/EquationDomain.h"

//COMMON headers
#include "COMMON/equa/PDEEquationEnsembleStrategy.h"
#include "COMMON/equa/PhaseChangeGroup.h"
#include "COMMON/info/InfoManager.h"
#include "COMMON/tbox/LogMessage.h"

#include "COMMON/info/RegionInfo.h"

namespace FreeMAPs
{

EquationDomain::EquationDomain (
    const PDEEquationEnsembleStrategy* equation_ensemble):
    Parent (equation_ensemble->get_full_name(), "domain", false),
    d_equation_ensemble (equation_ensemble),
    d_phase_change_group (0)
{
    d_phase_change_group = new PhaseChangeGroup (this);
}



EquationDomain::~EquationDomain()
{
    this->clear();
}



void
EquationDomain::clear()
{
    Utilities::clear_pointer_object (d_phase_change_group);
}


void
EquationDomain::set_region_name(
        const std::string region_name)
{
    d_region_name = region_name;
}



const std::string&
EquationDomain::get_region_name() const
{
    return d_region_name;
}



void
EquationDomain::get_from_input (
    const InputDatabase* db)
{
    this->prepare_for_use (db);

    db->insert_allowable_key ("region_name");
    db->insert_allowable_key ("default_value_out_range");
    db->insert_allowable_key ("phase_change_group");

    db->check_allowable_keys ();

    /*
     * region_name
     */
    if( db->key_exists("region_name") && db->is_string("region_name") )
    {
        d_region_name = db->get_string("region_name");
    }

#if 0
    /*
     * build region
     */
    {
        const RegionInfo* region_info = InfoManager::get_instance()->get_region_info();

        db->check_requisite_key ("region_name", DataType::STRING, false, false);
        const std::string region_name = db->get_string ("region_name");

        if (!region_info->has_region (region_name))
        {
            LogMessage::use_improper_string_value(
                this->get_database(),
                "region_name",
                region_name,
                "it should be a region's name set in \"region_info\"",
                Utilities::get_map_keys (region_info->get_regions()));
        }
        else
        {
            d_region = region_info->get_region (region_name);
        }
    }

    /*
     * set DefaultValueOutRange
     * this should be done after equation is build.
     */
    {
        db->check_requisite_database ("default_value_out_range");
        d_default_value_out_range.get_from_input (db->get_database ("default_value_out_range"));
    }

    /*
     * build phase_change_group
     */
    {
        db->check_optional_key ("phase_change_group", DataType::DATABASE, false, false);
        if (db->key_exists ("phase_change_group"))
        {
            d_phase_change_group = new PhaseChangeGroup (this);
            d_phase_change_group->get_from_input (db->get_database ("phase_change_group"));
        }
    }
#endif
}



std::ostream&
operator << (
    std::ostream& os,
    const EquationDomain& rhs)
{
    os << "domain\n{\n";

    std::ostringstream oss;

//    const std::map<std::string, Region*> map_region = InfoManager::get_instance()->get_region_info()->get_regions();
    /*
     * output region name
     */
    {
//        os << LogMessage::get_prefix (ONE_TAB) << "region_name = \"" << rhs.d_region->get_region_name() << "\"\n";
        os << LogMessage::get_prefix (ONE_TAB) << "region_name = \"" << rhs.d_region_name << "\"\n";
    }

#if 0
    /*
     * output phase_change_group
     */
    {
        if(rhs.d_equation_ensemble->get_equation_ensemble_type() == EquationEnsembleType::HEAT_CONDUCTION)
        {
            if (rhs.d_phase_change_group)
            {
                oss.str ("");
                oss << *rhs.d_phase_change_group;
                os << '\n' << LogMessage::get_log_info (
                       oss,
                       ONE_TAB) << '\n';
            }
        }
    }
#endif
    os << "}";

    return os;
}

} // namespace FreeMAPs
